package com.example.zyl.common;

import cn.hutool.db.Entity;
import com.example.zyl.common.utils.ToolUtils;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class CommonHelper {

    /**
     * 根据id查询数据
     *
     * @param id    id
     * @param clazz 类名
     * @return 实体类对象
     */
    public static <T> T selectById(Class<T> clazz, Serializable id) {
        // 获取主键列名
        String primaryKey = ToolUtils.getKeyColumn(clazz);
        // 根据主键查询
        String byClassSql = ToolUtils.getByClassSql(clazz).concat(" where " + primaryKey + " = ?");
        // 查询
        List<Entity> entityList = ToolUtils.getRowsBySql(clazz, byClassSql, id);
        // 转换成对象
        if (entityList == null || entityList.isEmpty()) {
            return null;
        }
        // 转换成对象
        Entity entity = entityList.get(0);
        return entity.toBean(clazz);
    }


    /**
     * 根据id查询数据
     *
     * @param id         id
     * @param clazz      类名
     * @param primaryKey 指定主键列名
     * @return 实体类对象
     */
    public static <T> T selectById(Class<T> clazz, Serializable id, String primaryKey) {

        if (ToolUtils.isEmpty(primaryKey)) {
            return selectById(clazz, id);
        }
        // 根据主键查询
        String byClassSql = ToolUtils.getByClassSql(clazz).concat(" where " + primaryKey + " = ?");
        // 查询
        List<Entity> entityList = ToolUtils.getRowsBySql(clazz, byClassSql, id);
        // 转换成对象
        if (entityList == null || entityList.isEmpty()) {
            return null;
        }
        // 转换成对象
        Entity entity = entityList.get(0);
        return entity.toBean(clazz);
    }


    /**
     * 根据多个id查询数据
     *
     * @param serializables 主键集合
     * @param clazz         类名
     * @return 实体类对象
     */
    public static <T> List<T> selectByIds(Class<T> clazz, Collection<Serializable> serializables) {

        if (serializables == null || serializables.isEmpty()) {
            return null;
        }
        // 获取主键列名
        String primaryKey = ToolUtils.getKeyColumn(clazz);
        // 转为参数
        StringBuilder serializableStr = new StringBuilder(" ");
        for (Serializable serializable : serializables) {
            serializableStr.append("?");
            serializableStr.append(serializable);
            serializableStr.append(",");
        }
        serializableStr.deleteCharAt(serializableStr.length() - 1);
        //转为参数Map
        Map<String, String> paramsMap = serializables.stream()
                .collect(Collectors.toMap(Serializable::toString, Serializable::toString, (k, v) -> v));

        // 根据主键查询
        String byClassSql = ToolUtils.getByClassSql(clazz).concat(" where " + primaryKey + " in ( " + serializableStr + " )");
        // 查询
        List<Entity> entityList = ToolUtils.getRowsBySql(clazz, byClassSql, paramsMap);
        // 转换成对象
        return resultToEntity(clazz, entityList);
    }


    /**
     * 查询所有数据
     *
     * @param clazz 类名
     * @return 查询结果
     */
    public static <T> List<T> selectList(Class<T> clazz) {

        // 获取查询sql
        String byClassSql = ToolUtils.getByClassSql(clazz);
        // 执行查询
        List<Entity> entityList = ToolUtils.getRowsBySql(clazz, byClassSql, null);
        // 转换成对象
        return resultToEntity(clazz, entityList);
    }



    /**
     * 根据条件查询数据
     *
     * @param clazz     类名
     * @param condition 条件
     * @return 查询结果
     */
    public static <T> List<T> selectList(Class<T> clazz, Object condition) {

        // 为空则查询所有
        if (condition == null) {
            return selectList(clazz);
        }
        // 根据类获取查询sql
        String byClassSql = ToolUtils.getByClassSql(clazz);
        // 根据查询对象获取查询条件sql
        String whereSql = ToolUtils.getSqlByObj(condition);
        // 组合sql
        String querySql = byClassSql.concat(whereSql);
        // 获取参数
        Map<String, Object> params = ToolUtils.objToMap(condition);
        // 执行查询
        List<Entity> entityList = ToolUtils.getRowsBySql(clazz, querySql, params);
        // 转换成对象
        return resultToEntity(clazz, entityList);
    }



    /**
     * 插入单条数据
     *
     * @param data 实体类对象
     * @return 是否插入成功
     */
    public static <T> boolean insert(T data) {
        if (data == null) {
            return false;
        }
        // 获取类名
        Class<?> clazz = data.getClass();
        // 获取插入sql语句
        String insertSql = ToolUtils.insertByClassSql(clazz, 1);
        // 具体的值
        Map<String, Object> params = ToolUtils.insertObjToMap(data);
        // 执行插入
        int result = ToolUtils.insertBySql(clazz, insertSql, params);
        // 判断是否插入成功
        return result > 0;
    }



    /**
     * 插入多条数据
     *
     * @param data 实体类对象
     * @return 是否插入成功
     */
    public static <T> boolean insertBatch(Class<?> clazz, List<T> data) {
        if (data == null) {
            return false;
        }
        // 获取插入sql语句
        String insertSql = ToolUtils.insertByClassSql(clazz, data.size());
        // 具体的值
        Map<String, Object> params = ToolUtils.insertObjToMap(data);
        // 执行插入
        int result = ToolUtils.insertBySql(clazz, insertSql, params);
        // 判断是否插入成功
        return result > 0;
    }



    /**
     * 将查询结果转换成对象
     *
     * @param clazz      类名
     * @param entityList 查询结果
     * @param <T>        实体类
     * @return 实体类对象
     */
    public static <T> List<T> resultToEntity(Class<T> clazz, List<Entity> entityList) {
        // 转换成对象
        if (entityList == null || entityList.isEmpty()) {
            return null;
        }
        // 转换成对象
        return entityList.stream()
                .map(entity -> entity.toBean(clazz))
                .collect(Collectors.toList());
    }

}
